/**
 * 基于 fetch 的 SSE 请求处理工具
 */

/**
 * 请求配置类型定义
 * @typedef {Object} RequestOptions
 * @property {string} method - 请求方法：'GET' 或 'POST'
 * @property {Object} headers - 请求头
 * @property {Object} body - 请求体（POST 请求使用）
 * @property {Object} params - URL 参数（GET 请求使用）
 * @property {string} contentType - 内容类型
 * @property {boolean} withCredentials - 是否携带凭证
 */

/**
 * SSE 配置类型定义
 * @typedef {Object} SSEOptions
 * @property {string} eventType - 事件类型
 * @property {number} retryCount - 重试次数
 * @property {number} retryDelay - 重试延迟（毫秒）
 */

/**
 * 发起 SSE 请求
 * @param {string} url - 请求地址
 * @param {RequestOptions} options - 请求配置
 * @param {SSEOptions} sseOptions - SSE 配置
 * @param {Function} onMessage - 消息处理回调
 * @param {Function} onError - 错误处理回调
 * @returns {Promise} 返回一个 Promise 对象
 */
export function fetchSSE(url, options = {}, sseOptions = {}, onMessage, onError) {
  return new Promise((resolve, reject) => {
    try {
      // 默认请求配置
      const defaultOptions = {
        method: 'GET',
        headers: {},
        params: {},
        contentType: 'application/json',
        withCredentials: true,
      };

      // 默认 SSE 配置
      const defaultSSEOptions = {
        eventType: 'message',
        retryCount: 3,
        retryDelay: 1000,
      };

      // 合并配置
      const requestOptions = {
        ...defaultOptions,
        ...options,
        headers: {
          'Content-Type': options.contentType || defaultOptions.contentType,
          'Accept': 'text/event-stream',
          'Cache-Control': 'no-cache',
          'Connection': 'keep-alive',
          ...options.headers,
        },
      };

      const sseConfig = {
        ...defaultSSEOptions,
        ...sseOptions,
      };

      // 处理 GET 请求参数
      if (requestOptions.method.toUpperCase() === 'GET' && requestOptions.params) {
        const params = new URLSearchParams();
        Object.entries(requestOptions.params).forEach(([key, value]) => {
          params.append(key, value);
        });
        url = `${url}${url.includes('?') ? '&' : '?'}${params.toString()}`;
      }

      // 处理 POST 请求
      if (requestOptions.method.toUpperCase() === 'POST') {
        // 处理请求体
        if (requestOptions.body) {
          requestOptions.body = JSON.stringify(requestOptions.body);
        }

        // 先发起 POST 请求获取会话 ID
        fetch(url, {
          ...requestOptions,
          headers: {
            ...requestOptions.headers,
            'Accept': 'application/json', // 修改 Accept 头以获取 JSON 响应
          },
        })
          .then(response => {
            if (!response.ok) {
              throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
          })
          .then(data => {
            // 从响应中获取会话 ID
            const sessionId = data?.sessionId || data?.data?.sessionId;
            if (!sessionId) {
              throw new Error('Failed to get session ID from response');
            }

            // 使用会话 ID 建立 SSE 连接
            const sseUrl = `${url}${url.includes('?') ? '&' : '?'}sessionId=${sessionId}`;
            console.log('建立 SSE 连接:', sseUrl);

            // 发起 SSE 请求
            fetch(sseUrl, {
              ...requestOptions,
              method: 'GET', // SSE 连接使用 GET 方法
              headers: {
                ...requestOptions.headers,
                'Accept': 'text/event-stream', // 恢复 SSE 所需的 Accept 头
              },
            })
              .then(response => {
                if (!response.ok) {
                  throw new Error(`SSE connection failed! status: ${response.status}`);
                }

                // 获取读取器
                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let buffer = '';
                let retryCount = 0;

                // 处理流数据
                function processStream() {
                  reader.read()
                    .then(({ done, value }) => {
                      if (done) {
                        console.log('Stream complete');
                        resolve();
                        return;
                      }

                      // 解码数据
                      const chunk = decoder.decode(value, { stream: true });
                      buffer += chunk;

                      // 处理完整的事件
                      const lines = buffer.split('\n');
                      buffer = lines.pop() || ''; // 保留最后一个不完整的事件

                      lines.forEach(line => {
                        if (line.startsWith('data: ')) {
                          const data = line.slice(6);
                          try {
                            const parsedData = JSON.parse(data);
                            onMessage(parsedData, false);
                          } catch (e) {
                            console.error('解析数据失败:', e);
                          }
                        }
                      });

                      // 继续读取
                      processStream();
                    })
                    .catch(error => {
                      console.error('读取流数据失败:', error);
                      if (retryCount < sseConfig.retryCount) {
                        retryCount++;
                        console.log(`尝试第 ${retryCount} 次重新连接...`);
                        setTimeout(() => {
                          processStream();
                        }, sseConfig.retryDelay);
                      } else {
                        onError(error);
                        reject(error);
                      }
                    });
                }

                // 开始处理流
                processStream();
              })
              .catch(error => {
                console.error('SSE 连接失败:', error);
                onError(error);
                reject(error);
              });
          })
          .catch(error => {
            console.error('POST 请求失败:', error);
            onError(error);
            reject(error);
          });
      } else {
        // GET 请求直接建立 SSE 连接
        fetch(url, requestOptions)
          .then(response => {
            if (!response.ok) {
              throw new Error(`HTTP error! status: ${response.status}`);
            }

            // 获取读取器
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';
            let retryCount = 0;

            // 处理流数据
            function processStream() {
              reader.read()
                .then(({ done, value }) => {
                  if (done) {
                    console.log('Stream complete');
                    resolve();
                    return;
                  }

                  // 解码数据
                  const chunk = decoder.decode(value, { stream: true });
                  buffer += chunk;

                  // 处理完整的事件
                  const lines = buffer.split('\n');
                  buffer = lines.pop() || ''; // 保留最后一个不完整的事件

                  lines.forEach(line => {
                    if (line.startsWith('data: ')) {
                      const data = line.slice(6);
                      try {
                        const parsedData = JSON.parse(data);
                        onMessage(parsedData, false);
                      } catch (e) {
                        console.error('解析数据失败:', e);
                      }
                    }
                  });

                  // 继续读取
                  processStream();
                })
                .catch(error => {
                  console.error('读取流数据失败:', error);
                  if (retryCount < sseConfig.retryCount) {
                    retryCount++;
                    console.log(`尝试第 ${retryCount} 次重新连接...`);
                    setTimeout(() => {
                      processStream();
                    }, sseConfig.retryDelay);
                  } else {
                    onError(error);
                    reject(error);
                  }
                });
            }

            // 开始处理流
            processStream();
          })
          .catch(error => {
            console.error('请求失败:', error);
            onError(error);
            reject(error);
          });
      }
    } catch (error) {
      console.error('初始化请求失败:', error);
      onError(error);
      reject(error);
    }
  });
}

/**
 * 手动处理流数据
 * @param {ReadableStream} stream - 可读流
 * @param {Function} onChunk - 数据块处理回调
 * @param {Function} onError - 错误处理回调
 * @returns {Promise} 返回一个 Promise 对象
 */
export function processStream(stream, onChunk, onError) {
  return new Promise((resolve, reject) => {
    const reader = stream.getReader();
    const decoder = new TextDecoder();
    let buffer = '';

    function read() {
      reader.read()
        .then(({ done, value }) => {
          if (done) {
            if (buffer) {
              try {
                onChunk(buffer);
              } catch (e) {
                onError(e);
              }
            }
            resolve();
            return;
          }

          // 解码数据
          const chunk = decoder.decode(value, { stream: true });
          buffer += chunk;

          // 处理完整的事件
          const lines = buffer.split('\n');
          buffer = lines.pop() || ''; // 保留最后一个不完整的事件

          lines.forEach(line => {
            if (line.trim()) {
              try {
                onChunk(line);
              } catch (e) {
                onError(e);
              }
            }
          });

          // 继续读取
          read();
        })
        .catch(error => {
          console.error('处理流数据失败:', error);
          onError(error);
          reject(error);
        });
    }

    // 开始读取
    read();
  });
} 